import {header_length, messageType} from "@/websocket/ws_const"
import store from "@/store"
import * as types from "@/common/vuex.const"
//消息体定义
export default class Message {
	constructor() {
		this.headerLength = header_length;
		this.version = 1;
		this.messageType = 0;
		this.sequence = 0;
		this.commandType = 0;
		this.bodyLength = 0;
		this.body = new Uint8Array(0); //消息体 unit8Array
		this.buf = new DataView(new ArrayBuffer(0));
		this.bufOffset = 0;
	}

	encodeRequest(commandType, msgId, body) {
		this.messageType = messageType.REQ.key;
		this.sequence = msgId;
		this.commandType = commandType;
		this.bodyLength = body.byteLength;
		this.body = body;

		this._encode();
	}

	decode(arrayBuf) {
		this.buf = new DataView(arrayBuf);
		this.headerLength = this._getUint32Buf();
		this.version = this._getUint32Buf();
		this.messageType = this._getUint32Buf();
		this.sequence = this._getUint64Buf();
		this.commandType = this._getUint32Buf();
		this.bodyLength = this._getUint32Buf();
		let byteArr = [];
		for (let i = 0; i < this.bodyLength; i++) {
			byteArr.push(this._getUint8Buf())
		}
		this.body = new Uint8Array(byteArr);
	}


	_encode() {
		let arrayBuf = new ArrayBuffer(this.headerLength + this.bodyLength);
		this.buf = new DataView(arrayBuf);
		this._setUint32Buf(this.headerLength);
		this._setUint32Buf(this.version);
		this._setUint32Buf(this.messageType);
		this._setUint64Buf(this.sequence);
		this._setUint32Buf(this.commandType);
		this._setUint32Buf(this.bodyLength);
		for (let i = 0; i < this.bodyLength; i++) {
			this._setUint8Buf(this.body[i]);
		}
	}

	_setUint64Buf(val) {
		this.buf.setBigUint64(this.bufOffset, val, false);
		this.bufOffset = this.bufOffset + 8;
	}

	_setUint32Buf(val) {
		this.buf.setUint32(this.bufOffset, val, false);
		this.bufOffset = this.bufOffset + 4;
	}

	_setUint8Buf(val) {
		this.buf.setUint8(this.bufOffset, val);
		this.bufOffset = this.bufOffset + 1;
	}

	_getUint32Buf() {
		let val = this.buf.getUint32(this.bufOffset, false);
		this.bufOffset = this.bufOffset + 4;
		return val;
	}

	_getUint64Buf(){
		let val = this.buf.getBigUint64(this.bufOffset, false);
		this.bufOffset = this.bufOffset + 8;
		return val;
	}

	_getUint8Buf() {
		let val = this.buf.getUint8(this.bufOffset);
		this.bufOffset = this.bufOffset + 1;
		return val;
	}

	_incSeq() {
		store.commit(types.USER_STATE_PREFIX + types.INC_SEQ, 1);
		return store.state.user.vuex_seq;
	}
	_resetBufOffset() {
		this.bufOffset = 0;
	}
}

